package com.sc.nft.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.sc.nft.dao.*;
import com.sc.nft.entity.*;
import com.sc.nft.enums.*;
import com.sc.nft.exception.GlobalRunTimeException;
import com.sc.nft.helper.MessageQueueHelper;
import com.sc.nft.helper.MetaChainHepler;
import com.sc.nft.service.ChainCallbackService;
import com.sc.nft.service.MetaWalletService;
import com.sc.nft.util.WeChatUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

@Slf4j
@RequiredArgsConstructor
@Service
public class ChainCallbackServiceImpl implements ChainCallbackService {

    private final ChainCallBackLogDao chainCallBackLogDao;
    private final DigitalCollectionDao digitalCollectionDao;
    private final CollectionChainInitDetailsLogDao collectionChainInitDetailsLogDao;
    private final UserCollectionChainLogDao userCollectionChainLogDao;
    private final UserChainInfoDao userChainInfoDao;
    private final DaoChainInfoDao daoChainInfoDao;
    private final UserCollectionDao userCollectionDao;
    private final DaoCollectionStoreDao daoCollectionStoreDao;
    private final MetaChainHepler metaChainHepler;
    private final MessageQueueHelper messageQueueHelper;
    private final TransferCollectionWithoutRecordsDao transferCollectionWithoutRecordsDao;
    private final UserInfoDao userInfoDao;
    private final MetaWalletService metaWalletService;
    private final TradingRecycleLogDao tradingRecycleLogDao;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deploy(ChainCallBackLog chainCallBackLog) {
        log.info("NFT铸造回调交易hans：{}", chainCallBackLog.getTransactionHash());
        log.info("NFT铸造回调合约地址：{}", chainCallBackLog.getContractAddress());
        //获取藏品
        DigitalCollection digitalCollection = digitalCollectionDao.getOneByDeployTransactionHash(chainCallBackLog.getTransactionHash());
        if (chainCallBackLog.getIsSuccess()) {//成功
            Assert.notNull(digitalCollection, () -> new GlobalRunTimeException(StrUtil.format("发⾏商品失败(回调处理),原因:{}", "未找到对应的藏品")));
            Assert.isTrue(digitalCollectionDao.updateContractAddressAndContractStatusById(digitalCollection.getId(), chainCallBackLog.getContractAddress(), chainCallBackLog.getTransactionHash(), CollectionContractStatusEnum.DEPLOY_SUCCESS), () -> new GlobalRunTimeException(StrUtil.format("发⾏藏品合约失败(callback),原因:{}", "更新合约地址失败")));
            chainCallBackLogDao.updateStatusById(chainCallBackLog.getId(), ChainCallBackStatusEnum.PROCESSED_SUCESS);
        } else {//发通知
            chainCallBackLogDao.updateStatusById(chainCallBackLog.getId(), ChainCallBackStatusEnum.PROCESSED_FAIL);
            WeChatUtil.sendWeChatMessage(StrUtil.format("NFT铸造回调处理,链日志表id:{}", chainCallBackLog.getId()));
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void mint(ChainCallBackLog chainCallBackLog) {
        if (chainCallBackLog.getIsSuccess()) {
            //获取最近的一条
            CollectionChainInitDetailsLog collectionChainInitDetailsLog = collectionChainInitDetailsLogDao.getOneByTransactionHash(chainCallBackLog.getTransactionHash());
            //判断是否为空
            Assert.isTrue(ObjectUtil.isNotNull(collectionChainInitDetailsLog), () -> new GlobalRunTimeException(StrUtil.format("铸造(回调处理)未找到对应的藏品 交易Hash:{}", chainCallBackLog.getTransactionHash())));
            //修改上链状态和tokenId
            Assert.isTrue(collectionChainInitDetailsLogDao.updateTokenIdAndNumberingById(collectionChainInitDetailsLog.getId(), chainCallBackLog.getTokenId()), () -> new GlobalRunTimeException(StrUtil.format("铸造(回调处理)更新tokenId失败,Id:{}", collectionChainInitDetailsLog.getId())));
            chainCallBackLogDao.updateStatusById(chainCallBackLog.getId(), ChainCallBackStatusEnum.PROCESSED_SUCESS);
        } else {
            WeChatUtil.sendWeChatMessage(StrUtil.format("NFT发行回调处理失败,链回调日志表id:{}", chainCallBackLog.getId()));
            chainCallBackLogDao.updateStatusById(chainCallBackLog.getId(), ChainCallBackStatusEnum.PROCESSED_FAIL);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void mintBatch(ChainCallBackLog chainCallBackLog) {
        if (chainCallBackLog.getIsSuccess()) {
            String[] tokenIds = chainCallBackLog.getTokenIds().split(",");
            //获取最近的一条
            List<CollectionChainInitDetailsLog> list = collectionChainInitDetailsLogDao.getListByTransactionHash(chainCallBackLog.getTransactionHash());
            if(list.size() != tokenIds.length){
                WeChatUtil.sendWeChatMessage(StrUtil.format("NFT批量发行回调tokenId数量与交易传入数量不符合,链日志表id:{}", chainCallBackLog.getId()));
                chainCallBackLogDao.updateStatusById(chainCallBackLog.getId(), ChainCallBackStatusEnum.PROCESSED_FAIL);
                return;
            }

            for (int i = 0; i < list.size(); i++) {
                collectionChainInitDetailsLogDao.updateTokenIdAndNumberingById(list.get(i).getId(), Integer.valueOf(tokenIds[i]));
            }

            chainCallBackLogDao.updateStatusById(chainCallBackLog.getId(), ChainCallBackStatusEnum.PROCESSED_SUCESS);
        } else {
            chainCallBackLogDao.updateStatusById(chainCallBackLog.getId(), ChainCallBackStatusEnum.PROCESSED_FAIL);
            WeChatUtil.sendWeChatMessage(StrUtil.format("NFT批量发行回调处理失败,链回调日志表id:{}", chainCallBackLog.getId()));
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void transfer(ChainCallBackLog chainCallBackLog) {

        if (chainCallBackLog.getIsSuccess()) {
            UserCollectionChainLog userCollectionChainLog = userCollectionChainLogDao.getOneByTransactionHashAndTokenId(chainCallBackLog.getTransactionHash(),chainCallBackLog.getTokenId());
            Assert.isTrue(ObjectUtil.isNotNull(userCollectionChainLog), () -> new GlobalRunTimeException(StrUtil.format("藏品交易失败(callback),原因:未找到对应的上链记录,交易hash:{}", chainCallBackLog.getTransactionHash())));

            //幂等性校验
            if(userCollectionChainLog.getStatus() == UserChainLogStatusEnum.SUCCESS){
                chainCallBackLogDao.updateStatusById(chainCallBackLog.getId(), ChainCallBackStatusEnum.PROCESSED_SUCESS);
                return;
            }else if(userCollectionChainLog.getStatus() != UserChainLogStatusEnum.IN_CHINA){
                WeChatUtil.sendWeChatMessage(StrUtil.format("NFT交易回调处理失败,链日志表id:{}", chainCallBackLog.getId()));
                chainCallBackLogDao.updateStatusById(chainCallBackLog.getId(), ChainCallBackStatusEnum.PROCESSED_FAIL);
                return;
            }
            //修改链记录状态
            Assert.isTrue(userCollectionChainLogDao.updateStatusById(userCollectionChainLog.getId(), UserChainLogStatusEnum.SUCCESS), () -> new GlobalRunTimeException(StrUtil.format("藏品交易失败(callback),原因:更新上链记录状态失败,藏品上链记录id:{}", userCollectionChainLog.getId())));
            //目标用户
            UserChainInfo chainUserInfo = userChainInfoDao.getRegisterByUserId(userCollectionChainLog.getUserId());
            //DAO仓库
            DaoChainInfo daoChainInfo = daoChainInfoDao.getByDaoId(userCollectionChainLog.getDaoId());

            //fromUser转移到toUser
            if (ObjectUtil.isNotNull(chainUserInfo)) {
                userCollectionDao.updateChainUrl(userCollectionChainLog.getUserCollectionId(), userCollectionChainLog.getContractAddress(), ChainStatusEnum.ONLINE);
            }

            //IP商城转移到DAO仓库
            if (ObjectUtil.isNull(chainUserInfo) && ObjectUtil.isNotNull(daoChainInfo)) {
                daoCollectionStoreDao.updateChainInfo(userCollectionChainLog.getUserCollectionId(), userCollectionChainLog.getContractAddress(),
                        ChainStatusEnum.ONLINE, userCollectionChainLog.getDeployTransactionHash(), userCollectionChainLog.getTransactionHash(), userCollectionChainLog.getTokenId());
            }

            //如果是平台转移给用户  这个值是0
            if(ObjectUtil.isNotNull(userCollectionChainLog.getFromUserCollectionId()) && userCollectionChainLog.getFromUserCollectionId().intValue()>0){
                //修改fromUser藏品信息
                userCollectionDao.updateChainUrl(userCollectionChainLog.getFromUserCollectionId(), userCollectionChainLog.getContractAddress(), ChainStatusEnum.DEAL);
            }
            chainCallBackLogDao.updateStatusById(chainCallBackLog.getId(), ChainCallBackStatusEnum.PROCESSED_SUCESS);

            //目标用户也新增一条记录
            UserCollectionChainLog fromUserCollectionChainLog = BeanUtil.copyProperties(userCollectionChainLog, UserCollectionChainLog.class);
            fromUserCollectionChainLog.setStatus(UserChainLogStatusEnum.SUCCESS);
            if (userCollectionChainLog.getCollectionType() == ReceivedCollectionType.RECEIVED) {
                fromUserCollectionChainLog.setDaoId(0l);
                fromUserCollectionChainLog.setUserId(userCollectionChainLog.getFromUserId());
                fromUserCollectionChainLog.setUserCollectionId(userCollectionChainLog.getFromUserCollectionId());
                fromUserCollectionChainLog.setCollectionType(ReceivedCollectionType.GIVE);
            } else if (userCollectionChainLog.getCollectionType() == ReceivedCollectionType.CONSIGN) {
                fromUserCollectionChainLog.setUserId(userCollectionChainLog.getFromUserId());
                fromUserCollectionChainLog.setUserCollectionId(userCollectionChainLog.getFromUserCollectionId());
            } else if (ReceivedCollectionType.PlatformTransaction().contains(userCollectionChainLog.getCollectionType())) {
                //如果是平台交易的，不需要新增一条记录
                return;
            }

            if(fromUserCollectionChainLog.getCollectionType() == ReceivedCollectionType.GIVE && fromUserCollectionChainLog.getUserId() == 0L){
                return;
            }

            fromUserCollectionChainLog.insert();

        } else {
            WeChatUtil.sendWeChatMessage(StrUtil.format("NFT交易回调处理失败,链日志表id:{}", chainCallBackLog.getId()));
            chainCallBackLogDao.updateStatusById(chainCallBackLog.getId(), ChainCallBackStatusEnum.PROCESSED_FAIL);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void transferToMetaWallet(ChainCallBackLog chainCallBackLog) throws IllegalAccessException {
        if (chainCallBackLog.getIsSuccess()) {
            UserCollectionChainLog userCollectionChainLog = userCollectionChainLogDao.getOneByTransactionHashAndTokenId(chainCallBackLog.getTransactionHash(),chainCallBackLog.getTokenId());
            Assert.isTrue(ObjectUtil.isNotNull(userCollectionChainLog), () -> new GlobalRunTimeException(StrUtil.format("藏品回收交易失败(callback),原因:未找到对应的上链记录,交易hash:{}", chainCallBackLog.getTransactionHash())));

            //幂等性校验
            if(userCollectionChainLog.getStatus() == UserChainLogStatusEnum.SUCCESS){
                chainCallBackLogDao.updateStatusById(chainCallBackLog.getId(), ChainCallBackStatusEnum.PROCESSED_SUCESS);
                return;
            }else if(userCollectionChainLog.getStatus() != UserChainLogStatusEnum.IN_CHINA){
                WeChatUtil.sendWeChatMessage(StrUtil.format("藏品转增交易失败,链日志表id:{}", chainCallBackLog.getId()));
                chainCallBackLogDao.updateStatusById(chainCallBackLog.getId(), ChainCallBackStatusEnum.PROCESSED_FAIL);
                return;
            }
            //修改链记录状态
            Assert.isTrue(userCollectionChainLogDao.updateStatusById(userCollectionChainLog.getId(), UserChainLogStatusEnum.SUCCESS), () -> new GlobalRunTimeException(StrUtil.format("藏品回收交易失败(callback),原因:更新上链记录状态失败,藏品上链记录id:{}", userCollectionChainLog.getId())));

            Long collectionId = userCollectionChainLog.getCollectionId();
            DigitalCollection collection = digitalCollectionDao.getById(collectionId);
            Assert.notNull(collection,()-> new GlobalRunTimeException("藏品不存在!"));

            // 把回收后的藏品设置为转增冻结中
            Assert.isTrue(collectionChainInitDetailsLogDao.updateDealStatusAndTransactionHashByCollectionIdAndNumbering(collection.getId(),userCollectionChainLog.getTransactionHash(),userCollectionChainLog.getTokenId(),CollectionChainDealStatusEnum.FROZEN),()-> new GlobalRunTimeException("藏品回收失败!"));
            //修改转增日志
            transferCollectionWithoutRecordsDao.updateStatusByUserCollectionChainId(userCollectionChainLog.getId(), TransferCollectionWithoutStatusEnum.SUCCESS,StrUtil.EMPTY,StrUtil.EMPTY);

            //MQ通知钱包开始添加藏品
            messageQueueHelper.sendMessage(MessageTopic.TRANSFER_TO_META_WALLET, userCollectionChainLog.getId());
            //通知钱包开始添加藏品
//            metaWalletService.transferToMetaWallet(userCollectionChainLog.getId());
        } else {
            WeChatUtil.sendWeChatMessage(StrUtil.format("藏品回收交易失败,链日志表id:{}", chainCallBackLog.getId()));
            chainCallBackLogDao.updateStatusById(chainCallBackLog.getId(), ChainCallBackStatusEnum.PROCESSED_FAIL);
        }
    }

    @Override
    public void transferFromMetaWallet(ChainCallBackLog chainCallBackLog) {
        if (chainCallBackLog.getIsSuccess()) {
            UserCollectionChainLog userCollectionChainLog = userCollectionChainLogDao.getOneByTransactionHashAndTokenId(chainCallBackLog.getTransactionHash(),chainCallBackLog.getTokenId());
            Assert.isTrue(ObjectUtil.isNotNull(userCollectionChainLog), () -> new GlobalRunTimeException(StrUtil.format("藏品交易失败(callback),原因:未找到对应的上链记录,交易hash:{}", chainCallBackLog.getTransactionHash())));

            //幂等性校验
            if(userCollectionChainLog.getStatus() == UserChainLogStatusEnum.SUCCESS){
                chainCallBackLogDao.updateStatusById(chainCallBackLog.getId(), ChainCallBackStatusEnum.PROCESSED_SUCESS);
                return;
            }else if(userCollectionChainLog.getStatus() != UserChainLogStatusEnum.IN_CHINA){
                WeChatUtil.sendWeChatMessage(StrUtil.format("NFT交易回调处理失败,链日志表id:{}", chainCallBackLog.getId()));
                chainCallBackLogDao.updateStatusById(chainCallBackLog.getId(), ChainCallBackStatusEnum.PROCESSED_FAIL);
                return;
            }
            //修改链记录状态
            Assert.isTrue(userCollectionChainLogDao.updateStatusById(userCollectionChainLog.getId(), UserChainLogStatusEnum.SUCCESS), () -> new GlobalRunTimeException(StrUtil.format("藏品交易失败(callback),原因:更新上链记录状态失败,藏品上链记录id:{}", userCollectionChainLog.getId())));
            //目标用户
            UserChainInfo chainUserInfo = userChainInfoDao.getRegisterByUserId(userCollectionChainLog.getUserId());

            //fromUser转移到toUser
            if (ObjectUtil.isNotNull(chainUserInfo)) {
                userCollectionDao.updateChainUrl(userCollectionChainLog.getUserCollectionId(), userCollectionChainLog.getContractAddress(), ChainStatusEnum.ONLINE);
            }

            chainCallBackLogDao.updateStatusById(chainCallBackLog.getId(), ChainCallBackStatusEnum.PROCESSED_SUCESS);
            //修改转增日志
            transferCollectionWithoutRecordsDao.updateStatusByUserCollectionChainId(userCollectionChainLog.getId(), TransferCollectionWithoutStatusEnum.SUCCESS,StrUtil.EMPTY,StrUtil.EMPTY);
            UserInfo user = userInfoDao.getById(userCollectionChainLog.getUserId());

            TransferCollectionWithoutRecords transferCollectionWithoutRecords = transferCollectionWithoutRecordsDao.getOneByUserCollectionChainLogId(userCollectionChainLog.getId());
            DigitalCollection collection = digitalCollectionDao.getById(userCollectionChainLog.getCollectionId());
            CollectionGiftLog collectionGiftLog = new CollectionGiftLog();
            collectionGiftLog.setTitle(collection.getFirstTitle());
            collectionGiftLog.setCollectionId(collection.getId());
            collectionGiftLog.setNumbering(userCollectionChainLog.getTokenId());
            collectionGiftLog.setPaymentSum(BigDecimal.ZERO);
            collectionGiftLog.setConsumeType(1);
            collectionGiftLog.setQuantityConsume(BigDecimal.ZERO.toPlainString());
            collectionGiftLog.setAddress(userCollectionChainLog.getToUserAddress());
            collectionGiftLog.setGiftUserId(0L);
            collectionGiftLog.setReceiveUserId(chainUserInfo.getUserId());
            collectionGiftLog.setGiftPropIds(StrUtil.EMPTY);
            collectionGiftLog.setGiveType(CollectionOriginalTypeEnum.MATE_WALLET);
            collectionGiftLog.setNumberingList(userCollectionChainLog.getTokenId().toString());
            collectionGiftLog.setToUserNickName(user.getNickName());
            collectionGiftLog.setToUserAddr(userCollectionChainLog.getToUserAddress());
            collectionGiftLog.setFromUserNickName(transferCollectionWithoutRecords.getFromUserNickName());
            collectionGiftLog.setFromUserAddr(userCollectionChainLog.getFromUserAddress());
            collectionGiftLog.insert();

            //仓库日志修改
            collectionChainInitDetailsLogDao.updateDealStatusByCollectionIdAndTokenId(userCollectionChainLog.getCollectionId(),userCollectionChainLog.getTokenId(),CollectionChainDealStatusEnum.TRADED);

        } else {
            WeChatUtil.sendWeChatMessage(StrUtil.format("NFT交易回调处理失败,链日志表id:{}", chainCallBackLog.getId()));
            chainCallBackLogDao.updateStatusById(chainCallBackLog.getId(), ChainCallBackStatusEnum.PROCESSED_FAIL);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void burn(ChainCallBackLog chainCallBackLog) {
        if (chainCallBackLog.getIsSuccess()) {
            UserCollectionChainLog userCollectionChainLog = userCollectionChainLogDao.getOneByTransactionHashAndStatus(chainCallBackLog.getTransactionHash(), UserChainLogStatusEnum.IN_CHINA, chainCallBackLog.getTokenId());
            Assert.isTrue(ObjectUtil.isNotNull(userCollectionChainLog), () -> new GlobalRunTimeException(StrUtil.format("藏品销毁失败(callback),原因:未找到对应的上链记录,交易hash:{}", chainCallBackLog.getTransactionHash())));

            Assert.isTrue(userCollectionChainLogDao.updateStatusById(userCollectionChainLog.getId(), UserChainLogStatusEnum.SUCCESS), () -> new GlobalRunTimeException(StrUtil.format("藏品销毁失败(callback),原因:更新上链记录状态失败,藏品上链记录id:{}", userCollectionChainLog.getId())));
            chainCallBackLogDao.updateStatusById(chainCallBackLog.getId(), ChainCallBackStatusEnum.PROCESSED_SUCESS);
        } else {
            chainCallBackLogDao.updateStatusById(chainCallBackLog.getId(), ChainCallBackStatusEnum.PROCESSED_FAIL);
            WeChatUtil.sendWeChatMessage(StrUtil.format("销毁回调处理失败,链日志表id:{}",chainCallBackLog.getId()));
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateMetaData(ChainCallBackLog chainCallBackLog) {
        if (chainCallBackLog.getIsSuccess()) {
            chainCallBackLogDao.updateStatusById(chainCallBackLog.getId(), ChainCallBackStatusEnum.PROCESSED_SUCESS);
        } else {
            WeChatUtil.sendWeChatMessage(StrUtil.format("修改元数据回调处理失败,链日志表id:{}", chainCallBackLog.getId()));
            chainCallBackLogDao.updateStatusById(chainCallBackLog.getId(), ChainCallBackStatusEnum.PROCESSED_FAIL);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateMetaDataBatch(ChainCallBackLog chainCallBackLog) {
        if (chainCallBackLog.getIsSuccess()) {
            chainCallBackLogDao.updateStatusById(chainCallBackLog.getId(), ChainCallBackStatusEnum.PROCESSED_SUCESS);
        } else {
            WeChatUtil.sendWeChatMessage(StrUtil.format("修改批量元数据回调处理失败,链日志表id:{}", chainCallBackLog.getId()));
            chainCallBackLogDao.updateStatusById(chainCallBackLog.getId(), ChainCallBackStatusEnum.PROCESSED_FAIL);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void transferBalance(ChainCallBackLog chainCallBackLog) {
        UserChainInfo userChainInfo = userChainInfoDao.getByUserId(1L);
        String transactionHash = metaChainHepler.transferBalance(userChainInfo.getUserKey(), chainCallBackLog.getToAddress(), chainCallBackLog.getAmount());
        chainCallBackLogDao.updateStatusAndTransactionHashById(userChainInfo.getId(),ChainCallBackStatusEnum.PROCESSED_SUCESS, transactionHash);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void recycleCollection(ChainCallBackLog chainCallBackLog) {
        if (chainCallBackLog.getIsSuccess()) {
            UserCollectionChainLog userCollectionChainLog = userCollectionChainLogDao.getOneByTransactionHashAndTokenId(chainCallBackLog.getTransactionHash(),chainCallBackLog.getTokenId());
            Assert.isTrue(ObjectUtil.isNotNull(userCollectionChainLog), () -> new GlobalRunTimeException(StrUtil.format("藏品回收交易失败(callback),原因:未找到对应的上链记录,交易hash:{}", chainCallBackLog.getTransactionHash())));

            //幂等性校验
            if(userCollectionChainLog.getStatus() == UserChainLogStatusEnum.SUCCESS){
                chainCallBackLogDao.updateStatusById(chainCallBackLog.getId(), ChainCallBackStatusEnum.PROCESSED_SUCESS);
                return;
            }else if(userCollectionChainLog.getStatus() != UserChainLogStatusEnum.IN_CHINA){
                WeChatUtil.sendWeChatMessage(StrUtil.format("藏品回收交易失败,链日志表id:{}", chainCallBackLog.getId()));
                chainCallBackLogDao.updateStatusById(chainCallBackLog.getId(), ChainCallBackStatusEnum.PROCESSED_FAIL);
                return;
            }
            //修改链记录状态
            Assert.isTrue(userCollectionChainLogDao.updateStatusById(userCollectionChainLog.getId(), UserChainLogStatusEnum.SUCCESS), () -> new GlobalRunTimeException(StrUtil.format("藏品回收交易失败(callback),原因:更新上链记录状态失败,藏品上链记录id:{}", userCollectionChainLog.getId())));

            //需要给
            // 1.在藏品表的可用库存+1
            Long collectionId = userCollectionChainLog.getCollectionId();
            DigitalCollection collection = digitalCollectionDao.getById(collectionId);
            Assert.notNull(collection,()-> new GlobalRunTimeException("藏品不存在!"));

            Assert.isTrue(digitalCollectionDao.addUsableAountById(collection.getId(),1),()-> new GlobalRunTimeException("藏品回收失败!"));
            // 2.sc_collection_chain_init_details_log(仓库表加一条可以交易的记录,合约地址,tokenId,)
//            CollectionChainInitDetailsLog collectionChainInitDetailsLog = new CollectionChainInitDetailsLog();
//            collectionChainInitDetailsLog.setCollectionId(collection.getId());
//            collectionChainInitDetailsLog.setStatus(UserChainLogStatusEnum.SUCCESS);
//            collectionChainInitDetailsLog.setDealStatus(CollectionChainDealStatusEnum.TRADEABLE);
//            collectionChainInitDetailsLog.setContractAddress(collection.getContractAddress());
//            collectionChainInitDetailsLog.setDeployTransactionHash(collection.getDeployTransactionHash());
//            collectionChainInitDetailsLog.setTransactionHash(userCollectionChainLog.getTransactionHash());
//            UserChainInfo userChainInfo = userChainInfoDao.getById(1L);
//            collectionChainInitDetailsLog.setUserAddress(userChainInfo.getAddress());
//            collectionChainInitDetailsLog.setNumbering(userCollectionChainLog.getTokenId());
//            collectionChainInitDetailsLog.setCollectionUuid(IdUtil.getSnowflakeNextIdStr());
//            collectionChainInitDetailsLog.setTokenId(userCollectionChainLog.getTokenId());
//            collectionChainInitDetailsLog.insert();

            // 08-16 调整为修改历史的记录的状态为可交易
            Assert.isTrue(collectionChainInitDetailsLogDao.updateDealStatusAndTransactionHashByCollectionIdAndNumbering(collection.getId(),userCollectionChainLog.getTransactionHash(),userCollectionChainLog.getTokenId()),()-> new GlobalRunTimeException("藏品回收失败!"));

            TradingRecycleLog tradingRecycleLog = tradingRecycleLogDao.getByUserCollectionChainLogId(userCollectionChainLog.getId());
            if (BeanUtil.isNotEmpty(tradingRecycleLog)) {
                // 如果存在的话.就要标记这个藏品被回收了.
                tradingRecycleLog.setStatus(Boolean.TRUE);
                tradingRecycleLog.updateById();
                // 藏品库存要-1
                Assert.isTrue(digitalCollectionDao.subUsableStock(collection.getId(),1)>0, () -> new GlobalRunTimeException(StrUtil.format("藏品回收交易成功.但是扣除库存失败(callback),原因:更新上链记录状态失败,藏品上链记录id:{},藏品id:{}", userCollectionChainLog.getId(),collection.getId())));
            }

        } else {
            WeChatUtil.sendWeChatMessage(StrUtil.format("藏品回收交易失败,链日志表id:{}", chainCallBackLog.getId()));
            chainCallBackLogDao.updateStatusById(chainCallBackLog.getId(), ChainCallBackStatusEnum.PROCESSED_FAIL);
        }
    }

    @Override
    public void ecologyDestroyCollection(ChainCallBackLog chainCallBackLog) {
        if (chainCallBackLog.getIsSuccess()) {
            UserCollectionChainLog userCollectionChainLog = userCollectionChainLogDao.getOneByTransactionHashAndStatus(chainCallBackLog.getTransactionHash(), UserChainLogStatusEnum.IN_CHINA, chainCallBackLog.getTokenId());
            Assert.isTrue(ObjectUtil.isNotNull(userCollectionChainLog), () -> new GlobalRunTimeException(StrUtil.format("藏品销毁失败(callback),原因:未找到对应的上链记录,交易hash:{}", chainCallBackLog.getTransactionHash())));

            Assert.isTrue(userCollectionChainLogDao.updateStatusById(userCollectionChainLog.getId(), UserChainLogStatusEnum.SUCCESS), () -> new GlobalRunTimeException(StrUtil.format("藏品销毁失败(callback),原因:更新上链记录状态失败,藏品上链记录id:{}", userCollectionChainLog.getId())));
            chainCallBackLogDao.updateStatusById(chainCallBackLog.getId(), ChainCallBackStatusEnum.PROCESSED_SUCESS);
        } else {
            chainCallBackLogDao.updateStatusById(chainCallBackLog.getId(), ChainCallBackStatusEnum.PROCESSED_FAIL);
            WeChatUtil.sendWeChatMessage(StrUtil.format("销毁回调处理失败,链日志表id:{}",chainCallBackLog.getId()));
        }
    }

    @Override
    public void tradingDestroyCollection(ChainCallBackLog chainCallBackLog) {
        if (chainCallBackLog.getIsSuccess()) {
            UserCollectionChainLog userCollectionChainLog = userCollectionChainLogDao.getOneByTransactionHashAndStatus(chainCallBackLog.getTransactionHash(), UserChainLogStatusEnum.IN_CHINA, chainCallBackLog.getTokenId());
            Assert.isTrue(ObjectUtil.isNotNull(userCollectionChainLog), () -> new GlobalRunTimeException(StrUtil.format("藏品销毁失败(callback),原因:未找到对应的上链记录,交易hash:{}", chainCallBackLog.getTransactionHash())));

            Assert.isTrue(userCollectionChainLogDao.updateStatusById(userCollectionChainLog.getId(), UserChainLogStatusEnum.SUCCESS), () -> new GlobalRunTimeException(StrUtil.format("藏品销毁失败(callback),原因:更新上链记录状态失败,藏品上链记录id:{}", userCollectionChainLog.getId())));
            chainCallBackLogDao.updateStatusById(chainCallBackLog.getId(), ChainCallBackStatusEnum.PROCESSED_SUCESS);
        } else {
            chainCallBackLogDao.updateStatusById(chainCallBackLog.getId(), ChainCallBackStatusEnum.PROCESSED_FAIL);
            WeChatUtil.sendWeChatMessage(StrUtil.format("销毁回调处理失败,链日志表id:{}",chainCallBackLog.getId()));
        }
    }

    @Override
    public void pledgeDestroyCollection(ChainCallBackLog chainCallBackLog) {
        if (chainCallBackLog.getIsSuccess()) {
            UserCollectionChainLog userCollectionChainLog = userCollectionChainLogDao.getOneByTransactionHashAndStatus(chainCallBackLog.getTransactionHash(), UserChainLogStatusEnum.IN_CHINA, chainCallBackLog.getTokenId());
            Assert.isTrue(ObjectUtil.isNotNull(userCollectionChainLog), () -> new GlobalRunTimeException(StrUtil.format("质押销毁失败(callback),原因:未找到对应的上链记录,交易hash:{}", chainCallBackLog.getTransactionHash())));

            Assert.isTrue(userCollectionChainLogDao.updateStatusById(userCollectionChainLog.getId(), UserChainLogStatusEnum.SUCCESS), () -> new GlobalRunTimeException(StrUtil.format("质押藏品销毁失败(callback),原因:更新上链记录状态失败,藏品上链记录id:{}", userCollectionChainLog.getId())));
            chainCallBackLogDao.updateStatusById(chainCallBackLog.getId(), ChainCallBackStatusEnum.PROCESSED_SUCESS);
        } else {
            chainCallBackLogDao.updateStatusById(chainCallBackLog.getId(), ChainCallBackStatusEnum.PROCESSED_FAIL);
            WeChatUtil.sendWeChatMessage(StrUtil.format("质押销毁回调处理失败,链日志表id:{}",chainCallBackLog.getId()));
        }
    }
}
